#ifndef __GL_PROTOCOL_H__
#define __GL_PROTOCOL_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "platform.h"

#define HEAD_G 			                        'G'
#define HEAD_L 			                        'L'
#define PROTOCOL_VERSION    	                0x01
#define PROTOCOL_VERSION_OTHER_LEN    	        (9)
#define FRAME_DATA_MAX_LEN                      (1024*2)
#define FRAME_ALL_MAX_LEN                       ( FRAME_DATA_MAX_LEN + PROTOCOL_VERSION_OTHER_LEN )



/****************** SYSTEM STA******************/
#define MASTER_CMD_SYSTEM						0x00

#define SLAVE_CMD_SYSTEM_REBOOT					0x00
#define SLAVE_CMD_SYSTEM_REBOOT_SUCCESS			0x01
#define SLAVE_CMD_SYSTEM_REBOOT_FAIL			0x02

#define SLAVE_CMD_SYSTEM_GET_VERSION			0x03
#define SLAVE_CMD_SYSTEM_GET_VERSION_SUCCESS	0x04
#define SLAVE_CMD_SYSTEM_GET_VERSION_FAIL		0x05

#define SLAVE_CMD_SYSTEM_ERROR				0xFF
/****************** SYSTEM END******************/

/****************** FLASH STA******************/
#define MASTER_CMD_FLASH						0xA0

#define SLAVE_CMD_FLASH_START					0x00
#define SLAVE_CMD_FLASH_START_SUCCESS			0x01
#define SLAVE_CMD_FLASH_START_FAIL				0x02

#define SLAVE_CMD_FLASH_TRANS					0x03
#define SLAVE_CMD_FLASH_TRANS_SUCCESS			0x04
#define SLAVE_CMD_FLASH_TRANS_FAIL				0x05

#define SLAVE_CMD_FLASH_CRC						0x06
#define SLAVE_CMD_FLASH_CRC_SUCCESS				0x07
#define SLAVE_CMD_FLASH_CRC_FAIL				0x08

#define SLAVE_CMD_FLASH_ERROR					0xFF
/****************** SYSTEM END******************/

typedef void (*rec_frame_callback)();
typedef void (*send_frame_fun)(uint8_t *arg1, uint16_t arg2);

typedef enum
{
    PARSE_OK,
    PARSE_FAIL
} PARSE_RETURN;

typedef enum
{
    USE_SERIAL,
    USE_TCP
} SEND_RECV_TYPE;

typedef enum
{
    NOHEAD,
    GETHEADHALF,
    GETHEAD,
    GETVERSION,
    GETLENHALF,
    GETLEN
} PARSE_DATA_STA;

typedef struct frame_struct
{
    uint8_t Version;
    uint16_t FrameDataLen;
    uint8_t MasterCmd;
    uint8_t SlaveCmd;
    uint8_t *frame_data;
    send_frame_fun send_frame_fun;
} FRAME_STRUCT;

typedef struct parse_struct
{
    PARSE_DATA_STA sta;
    uint16_t frame_cnt;
    uint16_t frame_data_len;
    uint16_t frame_len;
    uint8_t version;
    uint8_t frame_buffer[FRAME_ALL_MAX_LEN];
    rec_frame_callback rec_frame_cb;
    FRAME_STRUCT frame_s;
} PARSE_STRUCT;

PARSE_RETURN creat_send_cmd(FRAME_STRUCT *frame_s);

PARSE_RETURN parse_struct_init(PARSE_STRUCT *parse_s);
void parse_data(PARSE_STRUCT *parse_s, uint8_t *receive_buffer, uint16_t receive_len);

void frame_set_send_fun(FRAME_STRUCT *frame_s, send_frame_fun send_frame_fun);
void parse_set_send_fun(PARSE_STRUCT *parse_s, send_frame_fun send_frame_fun);
void parse_set_rec_callback(PARSE_STRUCT *parse_s, rec_frame_callback rec_frame_cb);

#ifdef __cplusplus
}
#endif

#endif
